package com.whity.towerdefense.view;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;
import java.util.Vector;

import javax.microedition.khronos.opengles.GL10;

import android.graphics.PointF;
import android.util.Log;

public class GraphicElt implements GraphicDrawable
{
	// =============================================================
	// Private attributs :
	
	@SuppressWarnings("unused")
	private static final String				TAG = "com.djm.test03.view";
	
	private FloatBuffer 					vertexBuffer;
	private ShortBuffer 					indexBuffer;
	private FloatBuffer 					textureBuffer;
	
	private final Vector<GraphicDrawable> 	m_Sons;
	private final GraphicHeart				m_GraphicHeart;
	
	protected float							m_Alpha;
	protected PointF 						m_Position;
	protected float 						m_ScaleX;
	protected float							m_ScaleY;
	protected float							m_Width;
	protected float							m_Height;
	
	//private float
	
	// =============================================================
	// Public functions :
	
	public GraphicElt(GraphicHeart p_GraphicHeart)
	{
		m_Sons = new Vector<GraphicDrawable>();
		m_Position = new PointF(0.0f, 0.0f);
		m_ScaleX = 1.0f;
		m_ScaleY = 1.0f;
		m_Alpha = 1.0f;
		m_GraphicHeart = p_GraphicHeart;
		m_Width = m_GraphicHeart.m_ResolutionX;
		m_Height =  m_GraphicHeart.m_ResolutionY;
		
		float vertices[] =
			{
		       0.0f,  m_Height, 0.0f,  // 0, Top Left
		       0.0f,  0.0f, 0.0f,  // 1, Bottom Left
		       m_Width,  0.0f, 0.0f,  // 2, Bottom Right
		       m_Width,  m_Height, 0.0f,  // 3, Top Right
			};
		
		float textureCoordinates[] =
			{
				0.0f, 0.0f,
                0.0f, 1.0f,
                1.0f, 1.0f,
                1.0f, 0.0f
			};
		ByteBuffer byteBuf = ByteBuffer.allocateDirect(textureCoordinates.length * 4);
		byteBuf.order(ByteOrder.nativeOrder());
		textureBuffer = byteBuf.asFloatBuffer();
		textureBuffer.put(textureCoordinates);
		textureBuffer.position(0);

		ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
		vbb.order(ByteOrder.nativeOrder());
		vertexBuffer = vbb.asFloatBuffer();
		vertexBuffer.put(vertices);
		vertexBuffer.position(0);
		
		short[] indices = { 0, 1, 2, 0, 2, 3 };
		ByteBuffer ibb = ByteBuffer.allocateDirect(indices.length * 2);
		ibb.order(ByteOrder.nativeOrder());
		indexBuffer = ibb.asShortBuffer();
		indexBuffer.put(indices);
		indexBuffer.position(0);
	}
	
	public void AddSon(GraphicDrawable p_Son)
	{
		synchronized(m_Sons)
		{
			m_Sons.add(p_Son);
		}
	}
	
	public void RemoveSon(GraphicDrawable p_Son)
	{
		synchronized(m_Sons)
		{
			m_Sons.remove(p_Son);
		}
	}
	
	public void Draw(GL10 p_GL)
	{
		p_GL.glPushMatrix();
		
			// Position and scale
			p_GL.glTranslatef(m_Position.x, m_Position.y, 0.0f);
			p_GL.glScalef(m_ScaleX, m_ScaleY, 1.0f);
			
			p_GL.glEnable(GL10.GL_TEXTURE_2D);
			p_GL.glBindTexture(GL10.GL_TEXTURE_2D, m_GraphicHeart.GetTextureID());
			p_GL.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
		
			p_GL.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
			p_GL.glColor4f(1.0f, 1.0f, 1.0f, m_Alpha);
			// Enabled the vertices buffer for writing and to be used during rendering.
			p_GL.glEnableClientState(GL10.GL_VERTEX_ARRAY);
			
				// Specifies the location and data format of an array of vertex coordinates to use when rendering.
				p_GL.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
				
				p_GL.glDrawElements(GL10.GL_TRIANGLES, indexBuffer.capacity(), GL10.GL_UNSIGNED_SHORT, indexBuffer);
		
			// Disable the vertices buffer.
			p_GL.glDisableClientState(GL10.GL_VERTEX_ARRAY);
			
			p_GL.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
			p_GL.glDisable(GL10.GL_TEXTURE_2D);
			
			synchronized(m_Sons)
			{
				// Draw sons :
				for(GraphicDrawable son : m_Sons)
				{
					son.Draw(p_GL);
				}
			}
			
		
		p_GL.glPopMatrix();
	}
	
	public PointF GetPosition()
	{
		return m_Position;
	}
	
	public void SetPosition(float p_X, float  p_Y)
	{
		m_Position.set(p_X, p_Y);
	}
	
	public float GetScale()
	{
		if(m_ScaleX == m_ScaleY)
			return m_ScaleX;
		else
			return -1;
	}
	
	public float GetScaleX()
	{
		return m_ScaleX;
	}
	
	public float GetScaleY()
	{
		return m_ScaleY;
	}
	
	public void SetScale(float p_Scale)
	{
		m_ScaleX = m_ScaleY = p_Scale;
	}
	
	public float GetWidth()
	{
		return m_Width;
	}
	
	public float GetHeight()
	{
		return m_Height;
	}
	
	/**
	 * Set the transparence of the tower. 0 = fully invisible, 1 = opaque
	 * @param p_Alpha in range [0, 1]
	 */
	public void SetAlpha(float p_Alpha)
	{
		m_Alpha = p_Alpha;
	}
	
	/**
	 * Get the transparence of the tower. 0 = fully invisible, 1 = opaque
	 * @return alpha value
	 */
	public float GetAlpha()
	{
		return m_Alpha;
	}
	
	// =============================================================
}
